<template>
  <div id="app">
    <el-container class="f">
      <el-aside>
        <el-tree :data="data" :props="defaultProps" @node-contextmenu="openMenu" @node-click="handleNodeClick"></el-tree>
      </el-aside>
      <el-main>
        <el-container style="margin-bottom: 12px;">
          <el-upload accept=".war,.jar" :multiple="false" :show-file-list="false" :on-success="uploadSuccess" action="/system/upload" style="margin-right: 10px;"><el-button size="mini">upload</el-button></el-upload>
          <el-button size="mini" @click="build">build</el-button>
          <el-button size="mini" @click="download">download</el-button>
        </el-container>
        <el-tabs v-model="currentFile" class="fileTab" type="card" @tab-click="handleTabClick" @tab-remove="handleTabRemove">
          <el-tab-pane v-for="(file,idx) in modifyFiles" :key="idx" :label="file.name" :name="file.path" class="codePane"></el-tab-pane>
        </el-tabs>
        <div v-if="id && modifyFiles && modifyFiles.length>0" class="monitor" v-html="monitorText"></div>
      </el-main>
    </el-container>
    <div v-show="contextMenuVisible"  class="context-menu">
      <el-menu @default-active="0" style="min-width:150px;border-right:0;">
        <el-menu-item index="1" @click="clickRightMenu(1)" class="right-item">新增</el-menu-item>
        <el-menu-item index="2" @click="clickRightMenu(2)" class="right-item">删除</el-menu-item>
      </el-menu>
    </div>
  </div>
</template>

<script>
import * as monaco from 'monaco-editor';
import {post,postOriginal} from "@/lib/request";
export default {
  name: 'App',
  components: {
  },
  data() {
    return {
      data: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      editor:null,
      modifyFiles:[],
      deleteFiles:[],
      id:"2",
      contextMenuVisible: false,
      contextMenuPosition: { x: 0, y: 0 },
      monitorText:'',
      currentNode:null,
      currentFile:null,

      editorConfig:{
        value: '',
        language: 'java',
        theme: 'vs-dark',
        scrollbar: { // 滚动条设置
          verticalScrollbarSize: 8, // 竖滚动条
          horizontalScrollbarSize: 8, // 横滚动条
        },
        fontSize: 16, // 字体大小
        tabSize: 2, // tab缩进长度
        autoIndent: true, // 自动布局
      }
    };
  },
  watch:{
  },
  async created() {
    this.loadJar()
  },
  mounted() {
    document.addEventListener('click', this.closeContextMenu);
    document.body.onresize=()=>{
      this.modifyFiles.forEach(file=>{
        file.editor.layout()
      })
    }
  },
  methods:{
    handleTabRemove(item){
      console.log(item)
    },
    handleTabClick(item){
      const obj=this.modifyFiles.filter(file=>file.path===item.name)[0]
      setTimeout(()=>{
        obj.editor.layout()
      },100)
    },
    async clickRightMenu(idx){
      if(!this.currentNode)return
      let dirPath;
      if(this.currentNode.dir){
        dirPath=this.currentNode.path
      }else{
        dirPath=this.currentNode.path.replace(this.currentNode.name,'')
      }
      if(idx===1){
        const {value}=await this.$prompt('', '请输入文件名', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputPattern: /[a-zA-Z_$][a-zA-Z_$0-9]*/,
          inputErrorMessage: '文件名格式不正确'
        })
        let fileName;
        if(value.indexOf('.')>=0){
          fileName=value
        }else{
          fileName=value+'.class'
        }
        console.log(fileName)
        let newNode={name:fileName,dir:false,path:dirPath+fileName,isChange:true,src:''}
        console.log(newNode)
        this.currentFile=newNode.path
        this.modifyFiles.push(newNode)

        this.$set(this.currentNode.children,this.currentNode.children.length,newNode)
        this.createEditor(newNode)
      }else if(idx===2){
        const index=this.modifyFiles.findIndex(item=>item===this.currentNode)
        this.modifyFiles.splice(index,1);
        this.deleteFiles.push(this.currentNode)
        this.removeNode(this.data,this.currentNode)
        console.log(this.deleteFiles)
      }
    },
    async openMenu(event,item){
      this.currentNode=item
      // 显示菜单并设置位置
      this.contextMenuVisible = true;
      this.contextMenuPosition.x = event.clientX;
      this.contextMenuPosition.y = event.clientY;
      // 阻止默认的右键菜单
      event.preventDefault();
    },
    closeContextMenu() {
      // 隐藏菜单
      this.contextMenuVisible = false;
    },
    handleMenuClick(action) {
      // 处理菜单项的点击事件
      this.closeContextMenu(); // 可选：点击后关闭菜单
    },
    async uploadJar(){

    },
    async loadJar(){
      if(!this.id)return
      const result=await post('/system/zipTree',{id:this.id});
      this.data=result.data
      this.modifyFiles.forEach(file=>file.editor.destroy())
      this.modifyFiles=[]
      this.deleteFiles=[]
      this.currentFile=null
      this.currentNode=null
    },
    async uploadSuccess(response, file, fileList){
      console.log(response)
      this.id=response.data
      this.loadJar()
    },
    async download(){
      const value=await postOriginal('/system/download',{id:this.id},{responseType:'blob'})
      console.log(value)
      if (value.headers['content-type'] === 'application/octet-stream') {
        //根据响应头获取文件名称
        let fileName = value.headers['content-disposition']?.match(/filename=(.*)/)[1]
        if (fileName) {
          fileName = decodeURI(fileName)
        } else {
          fileName = "download"
        }
        const blob = new Blob([value.data], {type: 'application/octet-stream'})
        if (typeof window.navigator.msSaveBlob !== 'undefined') {
          window.navigator.msSaveBlob(blob, fileName)
        } else {
          const blobURL = window.URL.createObjectURL(blob)
          const tempLink = document.createElement('a')
          tempLink.style.display = 'none'
          tempLink.href = blobURL
          tempLink.setAttribute('download', fileName)
          if (typeof tempLink.download === 'undefined') {
            tempLink.setAttribute('target', '_blank')
          }
          document.body.appendChild(tempLink)
          tempLink.click()
          document.body.removeChild(tempLink)
          window.URL.revokeObjectURL(blobURL)
        }
      }
    },
    async build(){
      if(!this.id)return
      const params={}
      for(let file of this.modifyFiles){
        params[file.path]=file.editor.getValue()
      }
      const result=await post('/system/save',{id:this.id,files:params})
      console.log(result)
      if(result.code==='200000'){
        this.monitorText=result.message.replaceAll('\n','<br>')
      }else{
        this.monitorText='SUCCESS'
      }
    },
    async handleNodeClick(item) {
      this.closeContextMenu()
      if(!this.id)return
      console.log(item);
      if(!item.dir){
        const idx=this.modifyFiles.findIndex(f=>f.path===item.path)
        if(idx>=0){
          this.currentFile=item.path

        }else{
          this.currentFile=item.path
          const result=await post('/system/decompile',{id:this.id,path:item.path});
          item.src=result.data
          item.isChange=false
          this.modifyFiles.push(item)
          this.createEditor(item)
        }
      }

    },
    createEditor(item){
      if(item.path.endsWith(".class")){
        this.editorConfig["language"]="java"
      }else if(item.path.endsWith(".xml")){
        this.editorConfig["language"]="xml"
      }else if(item.path.endsWith(".yml")){
        this.editorConfig["language"]="yaml"
      }else if(item.path.endsWith(".js")){
        this.editorConfig["language"]="javascript"
      }else if(item.path.endsWith(".sql")){
        this.editorConfig["language"]="sql"
      }else if(item.path.endsWith(".properties")){
        this.editorConfig["language"]="java"
      }else if(item.path.endsWith(".ts")){
        this.editorConfig["language"]="typescript"
      }else if(item.path.endsWith(".css")){
        this.editorConfig["language"]="css"
      }else if(item.path.endsWith(".html")||item.path.endsWith('.htm')){
        this.editorConfig["language"]="html"
      }else if(item.path.endsWith('ini')){
        this.editorConfig['language']='ini'
      }

      console.log(this.editorConfig)
      setTimeout(()=>{
        item.editor=monaco.editor.create(document.getElementById("pane-"+item.path),this.editorConfig)
        item.editor.setValue(item.src)
        item.editor.layout()
      },100)
    },
    removeNode(root,node){
      if(!root)return

      for(let i=0;i<root.length;i++){
        if(root[i].path===node.path){
          root.splice(i,1);
          break;
        }else{
          this.removeNode(root[i].children,node)
        }
      }
    }
  },
  beforeDestroy() {
    document.removeEventListener('click', this.closeContextMenu);
  },
}
</script>

<style>
*{
  margin:0;
  padding:0;
}
#app,body,html,.f{
  width: 100%;
  height: 100%;
}
.context-menu {
  position: absolute;
  left: v-bind(contextMenuPosition.x + 'px');
  top: v-bind(contextMenuPosition.y + 'px');
  border: 1px solid #ddd;
  background: #f1f1f1;
}
.right-item{
  line-height:40px!important;
  height:40px!important;
  border-bottom: 1px solid #d4d4d4!important;
}
.monitor{
  background: #666;padding:12px;height:160px;overflow-y:auto;color:white;
}
.fileTab .el-tabs__header{
  margin:0;
}
.codePane{
  width: 100%;
  height: calc(100vh - 310px);
}
</style>
